home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / human interface toolbox / dragwindowgrid / drawcode.c < prev   
Encoding:
C/C++ Source or Header  |  2000-06-23  |  7.6 KB  |  277 lines

  1. /*
  2.     File:        DrawCode.c
  3.  
  4.     Contains:    DragWindowGrid- a big nasty function to Drag a window along grid lines.  
  5.                 Note the elegant error handling.  You should change it to make your users happy.
  6.     
  7.                 You can change the size of the 'grid rects' by changing the value of kIncrement.
  8.  
  9.     Written by:     
  10.  
  11.     Copyright:    Copyright © 1999 by Apple Computer, Inc., All Rights Reserved.
  12.  
  13.                 You may incorporate this Apple sample source code into your program(s) without
  14.                 restriction. This Apple sample source code has been provided "AS IS" and the
  15.                 responsibility for its operation is yours. You are not permitted to redistribute
  16.                 this Apple sample source code as "Apple sample source code" after having made
  17.                 changes. If you're going to re-distribute the source, we require that you make
  18.                 it clear in the source that the code was descended from Apple sample source
  19.                 code, but that you've made changes.
  20.  
  21.     Change History (most recent first):
  22.                 8/5/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  23.                 
  24.  
  25. */
  26. #include <Windows.h>
  27. #include <QuickDraw.h>
  28. #include <TextUtils.h>
  29. #include <Fonts.h>
  30. #include <Memory.h>
  31.  
  32. void DragWindowGrid(WindowPtr win, Point pt);
  33. void DrawIt(WindowPtr win);
  34. pascal void DrawWindowContent(short pixelDepth, short dFlags, GDHandle theDevice, long theWin);
  35. void MyCreateNewWindow(void);
  36. void PreEventLoop(void);
  37. void DoUpdate(WindowPtr thisWindow);
  38. void PostEventLoop(void);
  39.  
  40. void DragWindowGrid(WindowPtr win, Point pt)
  41. {
  42.     RgnHandle    dragRgn, lastDragRgn, insetGray;
  43.     GrafPtr        oldPort, tmpPort;
  44.     Point        currPt, firstMulPoint, lastMulPoint, currMulPoint;
  45.     Boolean        frameHidden;
  46.     enum        {kIncrement = 16, kBorderInset = 4};
  47.  
  48.     // Set up our regions - init our variables.
  49.     dragRgn = NewRgn(); 
  50.     lastDragRgn = NewRgn(); 
  51.     insetGray = NewRgn();
  52.     if ((dragRgn == NULL) || (lastDragRgn == NULL) || (insetGray == NULL)) {
  53.         DebugStr("\pnot enough memory- bye!");
  54.         return;
  55.     }
  56.     CopyRgn(GetGrayRgn(), insetGray);
  57.     if (MemError() != noErr) {
  58.         DebugStr("\pnot enough memory- bye!");
  59.         return;
  60.     }
  61.  
  62.     InsetRgn(insetGray, kBorderInset, kBorderInset);
  63.     frameHidden = false;
  64.  
  65.     // Set up a port to draw into, and save off the old
  66.     tmpPort = (GrafPtr)NewPtr(sizeof(GrafPort));
  67.     if (tmpPort == NULL) {
  68.         DebugStr("\pnot enough memory- bye!");
  69.         return;
  70.     }
  71.     GetPort(&oldPort);
  72.     OpenPort(tmpPort);
  73.     CopyRgn(GetGrayRgn(), tmpPort->visRgn);
  74.     if (MemError() != noErr) {
  75.         DebugStr("\pnot enough memory- bye!");
  76.         return;
  77.     }
  78.     tmpPort->portRect = (*GetGrayRgn())->rgnBBox;
  79.     SetPort(tmpPort);
  80.     
  81.     PenMode(patXor);
  82.     PenPat(&qd.gray);
  83.  
  84.     // Set the incoming point to be on a multiple of kIncrement,
  85.     // to make later calculations easier.
  86.     currMulPoint.h = pt.h + (kIncrement/2);
  87.     currMulPoint.h /= kIncrement; currMulPoint.h *= kIncrement;
  88.     currMulPoint.v = pt.v + (kIncrement/2);
  89.     currMulPoint.v /= kIncrement; currMulPoint.v *= kIncrement;
  90.  
  91.     firstMulPoint = lastMulPoint = currMulPoint;
  92.  
  93.     CopyRgn(((WindowPeek)win)->strucRgn, dragRgn);
  94.     if (MemError() != noErr) {
  95.         DebugStr("\pnot enough memory- bye!");
  96.         return;
  97.     }
  98.  
  99.     CopyRgn(((WindowPeek)win)->strucRgn, lastDragRgn);
  100.     if (MemError() != noErr) {
  101.         DebugStr("\pnot enough memory- bye!");
  102.         return;
  103.     }
  104.  
  105.     // Draw the first framed region, which will follow the mouse
  106.     // on the screen
  107.     FrameRgn(lastDragRgn);
  108.  
  109.     while (WaitMouseUp() == true) {
  110.         // Now track the mouse, and when it moves enough make the framed
  111.         // region move as well.
  112.         GetMouse(&currPt);
  113.     
  114.         // Set the new point to be on a multiple of kIncrement
  115.         currMulPoint.h = currPt.h + (kIncrement/2);
  116.         currMulPoint.h /= kIncrement; currMulPoint.h *= kIncrement;
  117.         currMulPoint.v = currPt.v + (kIncrement/2);
  118.         currMulPoint.v /= kIncrement; currMulPoint.v *= kIncrement;
  119.  
  120.         // Should we be showing the frame region ??
  121.         if (PtInRgn(currPt, insetGray) == false) {
  122.             // It's somewhere near the edges, so hide the frame
  123.             if (frameHidden == false)
  124.                 // if it's not hidden already, hide it now
  125.                 FrameRgn(lastDragRgn);
  126.             frameHidden = true;
  127.         }
  128.         else {
  129.             // else, the frame should be shown if it's hidden
  130.             if (frameHidden == true) {
  131.                 FrameRgn(lastDragRgn);
  132.                 frameHidden = false;
  133.             }
  134.         }
  135.     
  136.         // Has the mouse moved ?
  137.         if (&currMulPoint != &lastMulPoint) {            
  138.             // The mouse coordinates have changed enough to adjust the window,
  139.             // so move the frame accordingly
  140.             OffsetRgn(dragRgn, currMulPoint.h - lastMulPoint.h, currMulPoint.v - lastMulPoint.v);
  141.  
  142.             if (frameHidden == false) {
  143.                 // Only show the frame if we're allowed to.
  144.                 FrameRgn(dragRgn);        
  145.                 FrameRgn(lastDragRgn);
  146.             }
  147.             lastMulPoint = currMulPoint;
  148.             CopyRgn(dragRgn, lastDragRgn);
  149.             if (MemError() != noErr) {
  150.                 DebugStr("\pnot enough memory- bye!");
  151.                 return;
  152.             }
  153.         }    
  154.     }
  155.     
  156.     if (frameHidden == false)
  157.         // If frameHidden is true, there's no need to erase the final
  158.         // frame.
  159.         FrameRgn(lastDragRgn);
  160.  
  161.     if ((&lastMulPoint != &firstMulPoint) && (frameHidden == false)) {
  162.         // The mouse has moved from its original position and is
  163.         // somewhere on the screen, so move the window accordingly.
  164.         Point    globalPt, diffPt, contPt = {0, 0};
  165.  
  166.         // Calculate the difference between the strucRgn's 0, 0 and
  167.         // the window's content region 0, 0.  Remember that MoveWindow
  168.         // moves the window's *content* to the coordinate specified, and
  169.         // we want to move the window's structure to fit in the lastDragRgn
  170.         SetPort(win);
  171.         // LocalToGlobal works much better when the port is set up...
  172.         LocalToGlobal(&contPt);
  173.         SetPort(tmpPort);
  174.         diffPt.h = contPt.h - (*((WindowPeek)win)->strucRgn)->rgnBBox.left;
  175.         diffPt.v = contPt.v - (*((WindowPeek)win)->strucRgn)->rgnBBox.top;
  176.         
  177.         globalPt.h = (*lastDragRgn)->rgnBBox.left;
  178.         globalPt.v = (*lastDragRgn)->rgnBBox.top;
  179.         LocalToGlobal(&globalPt);
  180.         globalPt.h += diffPt.h;
  181.         globalPt.v += diffPt.v;
  182.         MoveWindow(win, globalPt.h, globalPt.v, true);
  183.     }
  184.  
  185.     // Close the port and tear everything down
  186.     ClosePort(tmpPort);
  187.     SetPort(oldPort);
  188.     DisposeRgn(dragRgn);
  189.     DisposeRgn(insetGray);
  190.     DisposeRgn(lastDragRgn);
  191.     
  192. }
  193.  
  194.  
  195. /*-------------------------------------------------------------------------------------*/
  196.  
  197. void DrawIt(WindowPtr win)
  198. {
  199.     short         origFont, origSize;
  200.     
  201.     origFont = win->txFont;
  202.     origSize = win->txSize;
  203.     TextFont(kFontIDCourier);
  204.     TextSize(12);
  205.  
  206.     ForeColor(redColor);
  207.     PaintRect(&(*win).portRect);
  208.     ForeColor(blackColor);
  209.  
  210.     MoveTo(20, 20);
  211.     DrawString("\pDrag this window.");
  212.  
  213.     TextFont(origFont);
  214.     TextSize(origSize);
  215. }
  216.  
  217.  
  218. /*-------------------------------------------------------------------------------------*/
  219.  
  220. pascal void DrawWindowContent(short pixelDepth, short dFlags, GDHandle theDevice, long theWin)
  221. {
  222. #pragma unused (pixelDepth, dFlags, theDevice)
  223.     GrafPtr        savePort;
  224.  
  225.     GetPort(&savePort);
  226.     SetPort((GrafPtr)theWin);
  227.  
  228.     DrawIt((WindowPtr)theWin);
  229.  
  230.     SetPort(savePort);
  231. }
  232.  
  233.  
  234. /*-------------------------------------------------------------------------------------*/
  235.  
  236. void MyCreateNewWindow(void)
  237. {
  238.     Rect winDimension;
  239.     
  240.     SetRect(&winDimension, 60, 60, 460, 260);
  241.     (void)NewCWindow(0L, &winDimension, "\pSample", true, noGrowDocProc,
  242.                             (WindowPtr)-1L, true, 0L);
  243. }
  244.  
  245.  
  246. /*-------------------------------------------------------------------------------------*/
  247.  
  248. void PreEventLoop(void)
  249. {
  250.     MyCreateNewWindow();
  251. }
  252.  
  253.  
  254. /*-------------------------------------------------------------------------------------*/
  255.  
  256. void DoUpdate(WindowPtr thisWindow)
  257. {
  258.     static DeviceLoopDrawingUPP    procForDeviceLoop = nil;
  259.  
  260.     SetPort(thisWindow);
  261.  
  262.     if ( procForDeviceLoop == nil )
  263.         procForDeviceLoop = NewDeviceLoopDrawingProc(DrawWindowContent);    
  264.     
  265.     BeginUpdate(thisWindow);
  266.     DeviceLoop(thisWindow->visRgn, procForDeviceLoop, (long)thisWindow, singleDevices);
  267.     EndUpdate(thisWindow);
  268. }
  269.  
  270.  
  271. /*-------------------------------------------------------------------------------------*/
  272.  
  273. void PostEventLoop(void)
  274. {
  275. }
  276.  
  277.